using System;
using UnityEngine;
using GamePlay.Framework.Events;
using GamePlay.Features.Shared;

namespace GamePlay.Features.Core
{
    /// <summary>
    /// 玩家管理器，负责玩家数据的加载、保存和管理
    /// </summary>
    public class PlayerManager : MonoBehaviour
    {
        #region 单例实现

        private static PlayerManager _instance;

        public static PlayerManager Instance
        {
            get
            {
                if (_instance == null)
                {
                    GameObject obj = new GameObject("PlayerManager");
                    _instance = obj.AddComponent<PlayerManager>();
                    DontDestroyOnLoad(obj);
                }
                return _instance;
            }
        }

        private void Awake()
        {
            if (_instance != null && _instance != this)
            {
                Destroy(gameObject);
                return;
            }

            _instance = this;
            DontDestroyOnLoad(gameObject);

            // 注册事件
            RegisterEvents();
        }

        private void OnDestroy()
        {
            // 取消注册事件
            UnregisterEvents();
        }

        #endregion

        #region 字段和属性

        [SerializeField] private bool _debugMode = false;

        // 玩家数据
        private PlayerData _playerData;

        // 玩家状态
        private PlayerState _playerState = PlayerState.Idle;

        // 是否已初始化
        private bool _isInitialized = false;

        // 是否已登录
        private bool _isLoggedIn = false;

        // 公开属性
        public PlayerData PlayerData => _playerData;
        public PlayerState PlayerState => _playerState;
        public bool IsLoggedIn => _isLoggedIn;

        // 存档键名
        private const string PLAYER_DATA_KEY = "PlayerData";

        #endregion

        #region Unity生命周期

        private void Start()
        {
            if (!_isInitialized)
            {
                Initialize();
            }
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 初始化玩家管理器
        /// </summary>
        public void Initialize()
        {
            // 尝试加载玩家数据
            if (!LoadPlayerData())
            {
                // 如果没有找到存档，创建新数据
                Log("未找到玩家存档数据，创建新数据");
                CreateNewPlayer();
            }

            _isInitialized = true;
        }

        /// <summary>
        /// 创建新玩家
        /// </summary>
        /// <param name="playerName">玩家名称</param>
        public void CreateNewPlayer(string playerName = "Player")
        {
            string playerId = Guid.NewGuid().ToString();
            _playerData = PlayerData.CreateNew(playerId, playerName);

            // 保存到本地
            SavePlayerData();

            // 更新状态
            _isLoggedIn = true;

            // 触发玩家数据更新事件
            EmitPlayerDataUpdateEvent();

            Log($"创建新玩家: {playerName} (ID: {playerId})");
        }

        /// <summary>
        /// 保存玩家数据
        /// </summary>
        public void SavePlayerData()
        {
            if (_playerData == null)
            {
                LogWarning("无法保存玩家数据：数据为空");
                return;
            }

            try
            {
                // 更新最后登录时间
                _playerData.UpdateLastLoginTime();

                // 将数据转换为JSON
                string jsonData = JsonUtility.ToJson(_playerData);

                // 保存到PlayerPrefs
                PlayerPrefs.SetString(PLAYER_DATA_KEY, jsonData);
                PlayerPrefs.Save();

                Log("玩家数据已保存");
            }
            catch (Exception ex)
            {
                LogError($"保存玩家数据时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 加载玩家数据
        /// </summary>
        /// <returns>是否加载成功</returns>
        public bool LoadPlayerData()
        {
            try
            {
                // 从PlayerPrefs读取JSON数据
                if (PlayerPrefs.HasKey(PLAYER_DATA_KEY))
                {
                    string jsonData = PlayerPrefs.GetString(PLAYER_DATA_KEY);

                    // 解析JSON数据
                    _playerData = JsonUtility.FromJson<PlayerData>(jsonData);

                    // 更新状态
                    _isLoggedIn = true;

                    // 触发玩家数据更新事件
                    EmitPlayerDataUpdateEvent();

                    Log($"已加载玩家数据: {_playerData.PlayerName} (ID: {_playerData.PlayerId})");

                    return true;
                }
            }
            catch (Exception ex)
            {
                LogError($"加载玩家数据时出错: {ex.Message}");
            }

            return false;
        }

        /// <summary>
        /// 清除玩家数据
        /// </summary>
        public void ClearPlayerData()
        {
            if (PlayerPrefs.HasKey(PLAYER_DATA_KEY))
            {
                PlayerPrefs.DeleteKey(PLAYER_DATA_KEY);
                PlayerPrefs.Save();
            }

            _playerData = null;
            _isLoggedIn = false;

            Log("玩家数据已清除");
        }

        /// <summary>
        /// 更新玩家状态
        /// </summary>
        /// <param name="newState">新状态</param>
        public void UpdatePlayerState(PlayerState newState)
        {
            if (_playerState == newState)
                return;

            PlayerState oldState = _playerState;
            _playerState = newState;

            // 触发状态变化事件
            EmitEvent(new PlayerStateChangeArgs
            {
                PlayerId = _playerData.PlayerId,
                OldState = oldState,
                NewState = newState
            });

            Log($"玩家状态变更: {oldState} -> {newState}");
        }

        /// <summary>
        /// 添加经验值
        /// </summary>
        /// <param name="amount">经验值数量</param>
        /// <returns>是否升级</returns>
        public bool AddExperience(int amount)
        {
            if (!_isLoggedIn || _playerData == null)
                return false;

            bool isLevelUp = _playerData.AddExp(amount);

            // 保存数据
            SavePlayerData();

            // 触发玩家数据更新事件
            EmitPlayerDataUpdateEvent();

            if (isLevelUp)
            {
                Log($"玩家升级: {_playerData.Level}, 经验: {_playerData.Exp}");
            }

            return isLevelUp;
        }

        /// <summary>
        /// 添加金币
        /// </summary>
        /// <param name="amount">金币数量</param>
        public void AddGold(int amount)
        {
            if (!_isLoggedIn || _playerData == null)
                return;

            _playerData.AddGold(amount);

            // 保存数据
            SavePlayerData();

            // 触发玩家数据更新事件
            EmitPlayerDataUpdateEvent();

            Log($"添加金币: {amount}, 当前: {_playerData.Gold}");
        }

        /// <summary>
        /// 消费金币
        /// </summary>
        /// <param name="amount">金币数量</param>
        /// <returns>是否消费成功</returns>
        public bool SpendGold(int amount)
        {
            if (!_isLoggedIn || _playerData == null)
                return false;

            bool success = _playerData.SpendGold(amount);

            if (success)
            {
                // 保存数据
                SavePlayerData();

                // 触发玩家数据更新事件
                EmitPlayerDataUpdateEvent();

                Log($"消费金币: {amount}, 剩余: {_playerData.Gold}");
            }
            else
            {
                LogWarning($"金币不足，无法消费: {amount}, 当前: {_playerData.Gold}");
            }

            return success;
        }

        /// <summary>
        /// 记录游戏结果
        /// </summary>
        /// <param name="isWin">是否胜利</param>
        /// <param name="score">得分</param>
        /// <param name="playTime">游戏时间</param>
        public void RecordGameResult(bool isWin, int score, float playTime)
        {
            if (!_isLoggedIn || _playerData == null)
                return;

            _playerData.RecordGameResult(isWin, score);
            _playerData.AddPlayTime(playTime);

            // 保存数据
            SavePlayerData();

            // 触发玩家数据更新事件
            EmitPlayerDataUpdateEvent();

            Log($"记录游戏结果: 胜利={isWin}, 分数={score}, 游戏时间={playTime}秒");
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 注册事件
        /// </summary>
        private void RegisterEvents()
        {
            // 这里可以注册需要监听的事件
        }

        /// <summary>
        /// 取消注册事件
        /// </summary>
        private void UnregisterEvents()
        {
            // 取消注册已监听的事件
        }

        /// <summary>
        /// 触发玩家数据更新事件
        /// </summary>
        private void EmitPlayerDataUpdateEvent()
        {
            if (_playerData != null)
            {
                EmitEvent(new PlayerDataUpdateArgs
                {
                    PlayerId = _playerData.PlayerId,
                    Level = _playerData.Level,
                    Exp = _playerData.Exp,
                    Gold = _playerData.Gold
                });
            }
        }

        /// <summary>
        /// 发送事件
        /// </summary>
        private void EmitEvent<T>(T eventArgs) where T : EventArgs
        {
            EventManager.Instance.RaiseEvent(this, eventArgs);
        }

        /// <summary>
        /// 打印调试日志
        /// </summary>
        private void Log(string message)
        {
            if (_debugMode)
            {
                Debug.Log($"[PlayerManager] {message}");
            }
        }

        /// <summary>
        /// 打印警告日志
        /// </summary>
        private void LogWarning(string message)
        {
            Debug.LogWarning($"[PlayerManager] {message}");
        }

        /// <summary>
        /// 打印错误日志
        /// </summary>
        private void LogError(string message)
        {
            Debug.LogError($"[PlayerManager] {message}");
        }

        #endregion
    }
}